package com.ftwj.demo.utils.convertor;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import cn.hutool.core.util.ReflectUtil;
/**
 * 
*
* <p>Title: ListToTreeUtil</p>  
* <p>Description: List<Map>转List<Tree>的工具类</p>
* 
*
* [{id:1,name:1,pid:0},{id:2,name:2,pid:0}
* ,{id:11,name:11,pid:1},{id:12,name:12,pid:1},{id:21,name:21,pid:2},{id:22,name:22,pid:2}
* ,{id:111,name:111,pid:11}]
* 
*  [{id:1,name:1,pid:0,chidren:
*  		{id:11,name:11,pid:1,children:
*  			{id:111,name:111,pid:11}},
*  		{id:12,name:12,pid:1},
*  		{id:21,name:21,pid:2},
*  		{id:22,name:22,pid:2}},
*  {id:2,name:2,pid:0}]
*  
* <p>Copyright: Copyright (c) 2020 </p>  
* <p>Company: 兰州飞天网景信息产业有限公司</p>    
* @author WangSLi
* @date 2020年4月10日 上午11:05:56
* @version V1.0
 */
public abstract class ListToTreeUtil {
	
	static List<Map<String, Object>> list = new ArrayList<>();
	
	/**
	 * 
	 * <p>Title: buildMapTree</p>  
	 * <p>Description: 通过此方法可将数据库查询出的List结构的数据转化为树形结构 </p>  
	 * @param list
	 * @param rootId 根节点的ID
	 * @param rootName 根节点的字段名
	 * @param parnetIdName 父节点ID字段，如：pid,parentId 等
	 * @param childName 子树的名称，如：chilren,child 等
	 * @return 
	 * @author WangSLi
	 * @date 2020年4月7日  
	 * @version 1.0
	 */
	public static List<Map<String, Object>> buildMapTree(List<Map<String, Object>> list, String rootName, String rootId, String parnetName, String childName){
		CopyOnWriteArrayList<Map<String, Object>> copyList = new CopyOnWriteArrayList<>(list);
		List<Map<String, Object>> result=new LinkedList<Map<String, Object>>();
		for(Map<String, Object> map : copyList) {
			if(rootId.equals(map.get(parnetName).toString())) {
				result.add(map);
				copyList.remove(map);
				List<Map<String, Object>> rec = recursions(copyList,rootName,map.get(rootName).toString(),parnetName,childName);
				map.put(childName, rec);
				
			}
		}
		return result;
	} 
	
	/**
	 * `递归方法`
	 */
	private static List<Map<String, Object>> recursions(CopyOnWriteArrayList<Map<String, Object>> copyList, String rootName, String rootId, String parnetName, String childName) {
		List<Map<String, Object>> result=new LinkedList<Map<String, Object>>();
		for(Map<String, Object> map : copyList) {
			if(rootId.equals(map.get(parnetName).toString())) {
				copyList.remove(map);
				List<Map<String, Object>> rec = recursions(copyList, rootName, map.get(rootName).toString(), parnetName, childName);
				if(!rec.isEmpty()) {
					map.put(childName, rec);
				}
				result.add(map);
			}
		}
		return result;
	}
	
	/**
	 * 
	 * <p>Title: buildBeanTree</p>  
	 * <p>Description: 通过此方法可将数据库查询出的List结构的数据转化为树形结构 </p>  
	 * @param list
	 * @param cls 泛型T的类型T.class
	 * @param rootId 根节点的ID
	 * @param rootName 根节点的字段名
	 * @param parnetIdName 父节点ID字段，如：pid,parentId 等
	 * @param childName 子树的名称，如：chilren,child 等
	 * @return 
	 * @author WangSLi
	 * @date 2020年4月7日  
	 * @version 1.0
	 */
	public static <T> List<T>  buildBeanTree(List<T> list, Class<T> cls, String rootName, String rootId, String parnetName, String childName){
		CopyOnWriteArrayList<T> copyList = new CopyOnWriteArrayList<>(list);
		List<T> result=new LinkedList<>();
		for(T entity : copyList) {
			if(rootId.equals(ReflectUtil.getFieldValue(entity, parnetName).toString())) {
				result.add(entity);
				copyList.remove(entity);
				List<T> rec = recursion(copyList, cls, rootName, ReflectUtil.getFieldValue(entity, rootName).toString(), parnetName, childName);
				if(!rec.isEmpty()) {
					ReflectUtil.setFieldValue(entity, childName, rec);
				}
			}
		}
		return result;
	} 

	
	/**
	 * `递归方法`
	 */
	private static <T> List<T> recursion(CopyOnWriteArrayList<T> copyList, Class<T> cls, String rootName, String rootId, String parnetName, String childName) {
		List<T> result=new LinkedList<T>();
		for(T entity : copyList) {
			if(rootId.equals(ReflectUtil.getFieldValue(entity, parnetName).toString())) {
				copyList.remove(entity);
				List<T> rec = recursion(copyList, cls, rootName,ReflectUtil.getFieldValue(entity, rootName).toString(), parnetName, childName);
				if(!rec.isEmpty()) {
					ReflectUtil.setFieldValue(entity, childName, rec);
				}
				result.add(entity);
			}
		}
		return result;
	}

}
